﻿using Crap4Net;
using System;
using NUnit.Framework;
namespace Crap4Net.UnitTests.EntitiesTests
{
    [TestFixture]
    public class MethodSignatureTest
    {

        #region Additional test attributes
        // 
        //You can use the following additional attributes as you write your tests:
        //
        //Use ClassInitialize to run code before running the first test in the class
        //[ClassInitialize()]
        //public static void MyClassInitialize(TestContext testContext)
        //{
        //}
        //
        //Use ClassCleanup to run code after all tests in a class have run
        //[ClassCleanup()]
        //public static void MyClassCleanup()
        //{
        //}
        //
        //Use TestInitialize to run code before running each test
        //[TestInitialize()]
        //public void MyTestInitialize()
        //{
        //}
        //
        //Use TestCleanup to run code after each test has run
        //[TestCleanup()]
        //public void MyTestCleanup()
        //{
        //}
        //
        #endregion

        const string ASSEMBLY = "Assembly.dll";
        const string NAMESPACE = "NameSpace";
        const string TYPE_NAME = "SomeType";
        const string METHOD_NAME = "SomeMethod";
        readonly string[] SIGNATURE = new string[] { "int", "float" };

        [Test]
        public void ctor_LegalParameters_InitializeFieldsWithValues()
        {
            var target = new MethodSignature(
                ASSEMBLY,
                NAMESPACE,
                TYPE_NAME,
                METHOD_NAME,
                SIGNATURE);

            Assert.AreEqual(ASSEMBLY, target.AssemblyName);
            Assert.AreEqual(NAMESPACE, target.Namespace);
            Assert.AreEqual(TYPE_NAME, target.TypeName);
            Assert.AreEqual(METHOD_NAME, target.MethodName);
            CollectionAssert.AreEquivalent(SIGNATURE, target.Signature);
        }

        [Test]
        public void Equals_IdenticalValues_ReturnsTrue()
        {
            var target1 = new MethodSignature(
                ASSEMBLY,
                NAMESPACE,
                TYPE_NAME,
                METHOD_NAME,
                SIGNATURE);
            var target2 = new MethodSignature(
                ASSEMBLY,
                NAMESPACE,
                TYPE_NAME,
                METHOD_NAME,
                SIGNATURE);

            var actual = target1.Equals(target2);

            Assert.IsTrue(actual);
        }

        [Test]
        public void Equals_DifferentAssemblyName_ReturnsFalse()
        {
            var target1 = new MethodSignature(
                ASSEMBLY+"a",
                NAMESPACE,
                TYPE_NAME,
                METHOD_NAME,
                SIGNATURE);
            var target2 = new MethodSignature(
                ASSEMBLY,
                NAMESPACE,
                TYPE_NAME,
                METHOD_NAME,
                SIGNATURE);

            var actual = target1.Equals(target2);

            Assert.IsFalse(actual);
        }

        [Test]
        public void Equals_DifferentNameSpace_ReturnsFalse()
        {
            var target1 = new MethodSignature(
                ASSEMBLY,
                NAMESPACE + "a",
                TYPE_NAME,
                METHOD_NAME,
                SIGNATURE);
            var target2 = new MethodSignature(
                ASSEMBLY,
                NAMESPACE,
                TYPE_NAME,
                METHOD_NAME,
                SIGNATURE);

            var actual = target1.Equals(target2);

            Assert.IsFalse(actual);
        }

        [Test]
        public void Equals_DifferentTypeName_ReturnsFalse()
        {
            var target1 = new MethodSignature(
                ASSEMBLY,
                NAMESPACE,
                TYPE_NAME + "a",
                METHOD_NAME,
                SIGNATURE);
            var target2 = new MethodSignature(
                ASSEMBLY,
                NAMESPACE,
                TYPE_NAME,
                METHOD_NAME,
                SIGNATURE);

            var actual = target1.Equals(target2);

            Assert.IsFalse(actual);
        }

        [Test]
        public void Equals_DifferentMethodName_ReturnsFalse()
        {
            var target1 = new MethodSignature(
                ASSEMBLY,
                NAMESPACE,
                TYPE_NAME,
                METHOD_NAME,
                SIGNATURE);
            var target2 = new MethodSignature(
                ASSEMBLY,
                NAMESPACE,
                TYPE_NAME,
                METHOD_NAME + "a",
                SIGNATURE);

            var actual = target1.Equals(target2);

            Assert.IsFalse(actual);
        }

        [Test]
        public void Equals_DifferentSignature_ReturnsFalse()
        {
            var target1 = new MethodSignature(
                ASSEMBLY,
                NAMESPACE,
                TYPE_NAME,
                METHOD_NAME,
                SIGNATURE);
            var target2 = new MethodSignature(
                ASSEMBLY,
                NAMESPACE,
                TYPE_NAME,
                METHOD_NAME + "a",
                new string[]{});

            var actual = target1.Equals(target2);

            Assert.IsFalse(actual);
        }

        [Test]
        public void Equals_NullObject_ReturnsFalse()
        {
            var target = new MethodSignature(
                ASSEMBLY,
                NAMESPACE,
                TYPE_NAME,
                METHOD_NAME,
                SIGNATURE);

            var actual = target.Equals(null);

            Assert.IsFalse(actual);
        }

        [Test]
        public void Equals_MethodNameWithDifferentGenericArguments_ReturnsTrue()
        {
            var target1 = new MethodSignature(
                ASSEMBLY,
                NAMESPACE,
                TYPE_NAME,
                "method<T>",
                SIGNATURE);
            var target2 = new MethodSignature(
                ASSEMBLY,
                NAMESPACE,
                TYPE_NAME,
                "method<1>",
                SIGNATURE);

            var actual = target1.Equals(target2);

            Assert.IsTrue(actual);
        }

        [Test]
        public void Equals_MethodNameWithDifferentNumberOfGenericArguments_ReturnsFalse()
        {
            var target1 = new MethodSignature(
                ASSEMBLY,
                NAMESPACE,
                TYPE_NAME,
                "method<T,Y>",
                SIGNATURE);
            var target2 = new MethodSignature(
                ASSEMBLY,
                NAMESPACE,
                TYPE_NAME,
                "method<1>",
                SIGNATURE);

            var actual = target1.Equals(target2);

            Assert.IsFalse(actual);
        }
    }
}
